package chenji.gunapi.untl.asm;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import org.bukkit.Bukkit;

import com.avaje.ebean.enhance.asm.ClassWriter;
import com.avaje.ebean.enhance.asm.FieldVisitor;
import com.avaje.ebean.enhance.asm.Label;
import com.avaje.ebean.enhance.asm.MethodVisitor;
import com.avaje.ebean.enhance.asm.Opcodes;

import chenji.gunapi.Main;
import chenji.gunapi.untl.nbt.NBTManager;
import chenji.gunapi.untl.nbt.NMSItem;

public class AsmManager implements Opcodes {
	private final static AsmManager asm = new AsmManager();
	private Class<? extends NMSItem> nmsItemCopyClass;

	public static AsmManager getAsmManager() {
		return asm;
	}

	private final URLClassLoader loader;
	private final String version = Bukkit.getServer().getClass().getPackage().getName().substring(23);
	private final File datafolder = Main.getDataFold();
	private NBTManager nbtmanager;
	private boolean tryagain;

	public AsmManager() {
		URLClassLoader loader = null;
		try {
			loader = new URLClassLoader(new URL[] { datafolder.toURI().toURL() }, Main.class.getClassLoader());
		} catch (MalformedURLException e) {

			e.printStackTrace();
		}
		this.loader = loader;
		this.setupNBTEditor();
		this.setupNMSItem();

	}

	public NBTManager getNBTManager() {
		return this.nbtmanager;
	}

	public Class<?> loadClass(String name) throws ClassNotFoundException {
		return this.loader.loadClass(name);
	}

	public void setupNBTEditor() {

		File f = new File(datafolder + "/chenji/asmuntl");
		File f1 = new File(f + "/NBTEditor.class");
		if (!(f.exists())) {
			f.mkdirs();

		}
		if (!(f1.exists())) {
			this.writeFile(f1, this.getNBTEditorCode());
		}
		try {
			try {
				this.nbtmanager = (NBTManager) this.loadClass("chenji.asmuntl.NBTEditor").newInstance();
			} catch (InstantiationException | IllegalAccessException e) {
				if (this.tryagain == false) {
					this.tryagain = true;
					this.writeFile(f1, this.getNBTEditorCode());
				}
				e.printStackTrace();
				return;
			}
		} catch (ClassNotFoundException e) {
			if (this.tryagain == false) {
				this.tryagain = true;
				this.writeFile(f1, this.getNBTEditorCode());
			}
			e.printStackTrace();
			return;
		}
		this.tryagain = false;

	}

	@SuppressWarnings("unchecked")
	public void setupNMSItem() {

		File f = new File(datafolder + "/chenji/asmuntl");
		File f1 = new File(f + "/NMSItemCopy.class");
		if (!(f.exists())) {
			f.mkdirs();

		}
		if (!(f1.exists())) {
			this.writeFile(f1, this.getNMSItemCopyCode());
		}
		try {
			this.nmsItemCopyClass = (Class<? extends NMSItem>) this.loadClass("chenji.asmuntl.NMSItemCopy");
		} catch (ClassNotFoundException e) {
			if (this.tryagain == false) {
				this.tryagain = true;
				this.writeFile(f1, this.getNMSItemCopyCode());
			}
			e.printStackTrace();
			return;
		}
		this.tryagain = false;

	}

	private void writeFile(File file, byte[] bytes) {
		FileOutputStream stream = null;
		try {
			stream = new FileOutputStream(file);

		} catch (FileNotFoundException e) {
			try {
				file.createNewFile();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			this.writeFile(file, bytes);
		}
		try {
			stream.write(bytes);
			stream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				stream.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public byte[] getNBTEditorCode() {
		ClassWriter cw = new ClassWriter(0);
		MethodVisitor mv;
		cw.visit(52, ACC_PUBLIC + ACC_SUPER, "chenji/asmuntl/NBTEditor", null, "java/lang/Object", new String[] { "chenji/gunapi/untl/nbt/NBTManager" });

		cw.visitSource("NBTEditor.java", null);

		{
			mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitInsn(RETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(1, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getNMSCopy", "(Lorg/bukkit/inventory/ItemStack;)Ljava/lang/Object;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKESTATIC, "org/bukkit/craftbukkit/" + this.version + "/inventory/CraftItemStack", "asNMSCopy",
					"(Lorg/bukkit/inventory/ItemStack;)Lnet/minecraft/server/" + this.version + "/ItemStack;");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(1, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getBukkitCopy", "(Ljava/lang/Object;)Lorg/bukkit/inventory/ItemStack;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 1);
			Label l1 = new Label();
			mv.visitJumpInsn(IFNONNULL, l1);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l1);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitTypeInsn(INSTANCEOF, "net/minecraft/server/" + this.version + "/ItemStack");
			Label l3 = new Label();
			mv.visitJumpInsn(IFNE, l3);
			Label l4 = new Label();
			mv.visitLabel(l4);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l3);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitTypeInsn(CHECKCAST, "net/minecraft/server/" + this.version + "/ItemStack");
			mv.visitMethodInsn(INVOKESTATIC, "org/bukkit/craftbukkit/" + this.version + "/inventory/CraftItemStack", "asBukkitCopy",
					"(Lnet/minecraft/server/" + this.version + "/ItemStack;)Lorg/bukkit/inventory/ItemStack;");
			mv.visitInsn(ARETURN);
			Label l5 = new Label();
			mv.visitLabel(l5);
			mv.visitMaxs(1, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getNBTTagCompound", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 1);
			Label l1 = new Label();
			mv.visitJumpInsn(IFNONNULL, l1);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l1);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitTypeInsn(INSTANCEOF, "net/minecraft/server/" + this.version + "/ItemStack");
			Label l3 = new Label();
			mv.visitJumpInsn(IFNE, l3);
			Label l4 = new Label();
			mv.visitLabel(l4);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l3);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitTypeInsn(CHECKCAST, "net/minecraft/server/" + this.version + "/ItemStack");
			mv.visitVarInsn(ASTORE, 2);
			Label l5 = new Label();
			mv.visitLabel(l5);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/ItemStack", "getTag", "()Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ASTORE, 3);
			Label l6 = new Label();
			mv.visitLabel(l6);
			mv.visitVarInsn(ALOAD, 3);
			Label l7 = new Label();
			mv.visitJumpInsn(IFNONNULL, l7);
			Label l8 = new Label();
			mv.visitLabel(l8);
			mv.visitTypeInsn(NEW, "net/minecraft/server/" + this.version + "/NBTTagCompound");
			mv.visitInsn(DUP);
			mv.visitMethodInsn(INVOKESPECIAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "<init>", "()V");
			mv.visitVarInsn(ASTORE, 3);
			mv.visitLabel(l7);
			mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "net/minecraft/server/" + this.version + "/ItemStack", "net/minecraft/server/" + this.version + "/NBTTagCompound" }, 0, null);
			mv.visitVarInsn(ALOAD, 3);
			mv.visitInsn(ARETURN);
			Label l9 = new Label();
			mv.visitLabel(l9);
			mv.visitMaxs(2, 4);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setNBTTag", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 1);
			Label l1 = new Label();
			mv.visitJumpInsn(IFNONNULL, l1);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l1);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitTypeInsn(INSTANCEOF, "net/minecraft/server/" + this.version + "/ItemStack");
			Label l3 = new Label();
			mv.visitJumpInsn(IFNE, l3);
			Label l4 = new Label();
			mv.visitLabel(l4);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l3);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitTypeInsn(CHECKCAST, "net/minecraft/server/" + this.version + "/ItemStack");
			mv.visitVarInsn(ASTORE, 4);
			Label l5 = new Label();
			mv.visitLabel(l5);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "getNBTTagCompound", "(Ljava/lang/Object;)Ljava/lang/Object;");
			mv.visitTypeInsn(CHECKCAST, "net/minecraft/server/" + this.version + "/NBTTagCompound");
			mv.visitVarInsn(ASTORE, 5);
			Label l6 = new Label();
			mv.visitLabel(l6);
			mv.visitVarInsn(ALOAD, 5);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitVarInsn(ALOAD, 3);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setString", "(Ljava/lang/String;Ljava/lang/String;)V");
			Label l7 = new Label();
			mv.visitLabel(l7);
			mv.visitVarInsn(ALOAD, 4);
			mv.visitVarInsn(ALOAD, 5);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/ItemStack", "setTag", "(Lnet/minecraft/server/" + this.version + "/NBTTagCompound;)V");
			Label l8 = new Label();
			mv.visitLabel(l8);
			mv.visitVarInsn(ALOAD, 4);
			mv.visitInsn(ARETURN);
			Label l9 = new Label();
			mv.visitLabel(l9);
			mv.visitMaxs(3, 6);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getNBTTag", "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "getNBTTagCompound", "(Ljava/lang/Object;)Ljava/lang/Object;");
			mv.visitTypeInsn(CHECKCAST, "net/minecraft/server/" + this.version + "/NBTTagCompound");
			mv.visitVarInsn(ASTORE, 3);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 3);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getString", "(Ljava/lang/String;)Ljava/lang/String;");
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(2, 4);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getNBTTagFromItem", "(Lorg/bukkit/inventory/ItemStack;Ljava/lang/String;)Ljava/lang/String;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "getNMSCopy", "(Lorg/bukkit/inventory/ItemStack;)Ljava/lang/Object;");
			mv.visitVarInsn(ASTORE, 3);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 3);
			Label l2 = new Label();
			mv.visitJumpInsn(IFNONNULL, l2);
			Label l3 = new Label();
			mv.visitLabel(l3);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l2);
			mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/Object" }, 0, null);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 3);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "getNBTTag", "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;");
			mv.visitInsn(ARETURN);
			Label l4 = new Label();
			mv.visitLabel(l4);
			mv.visitMaxs(3, 4);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setNBTTagFromItem", "(Lorg/bukkit/inventory/ItemStack;Ljava/lang/String;Ljava/lang/String;)Lorg/bukkit/inventory/ItemStack;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "getNMSCopy", "(Lorg/bukkit/inventory/ItemStack;)Ljava/lang/Object;");
			mv.visitVarInsn(ASTORE, 4);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 4);
			Label l2 = new Label();
			mv.visitJumpInsn(IFNONNULL, l2);
			Label l3 = new Label();
			mv.visitLabel(l3);
			mv.visitInsn(ACONST_NULL);
			mv.visitInsn(ARETURN);
			mv.visitLabel(l2);
			mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/Object" }, 0, null);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 4);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitVarInsn(ALOAD, 3);
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "setNBTTag", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
			mv.visitMethodInsn(INVOKEVIRTUAL, "chenji/asmuntl/NBTEditor", "getBukkitCopy", "(Ljava/lang/Object;)Lorg/bukkit/inventory/ItemStack;");
			mv.visitInsn(ARETURN);
			Label l4 = new Label();
			mv.visitLabel(l4);
			mv.visitMaxs(5, 5);
			mv.visitEnd();
		}
		cw.visitEnd();

		return cw.toByteArray();

	}

	public byte[] getNMSItemCopyCode() {
		ClassWriter cw = new ClassWriter(0);
		FieldVisitor fv;
		MethodVisitor mv;

		cw.visit(52, ACC_PUBLIC + ACC_SUPER, "chenji/asmuntl/NMSItemCopy", null, "chenji/gunapi/untl/nbt/NMSItem", null);

		cw.visitSource("NMSItemCopy.java", null);

		{
			fv = cw.visitField(0, "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;", null, null);
			fv.visitEnd();
		}
		{
			fv = cw.visitField(0, "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;", null, null);
			fv.visitEnd();
		}
		{
			fv = cw.visitField(0, "item", "Lorg/bukkit/inventory/ItemStack;", null, null);
			fv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitMethodInsn(INVOKESPECIAL, "chenji/gunapi/untl/nbt/NMSItem", "<init>", "()V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ACONST_NULL);
			mv.visitFieldInsn(PUTFIELD, "chenji/asmuntl/NMSItemCopy", "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;");
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitInsn(RETURN);
			Label l3 = new Label();
			mv.visitLabel(l3);
			mv.visitMaxs(2, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setItem", "(Lorg/bukkit/inventory/ItemStack;)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitFieldInsn(PUTFIELD, "chenji/asmuntl/NMSItemCopy", "item", "Lorg/bukkit/inventory/ItemStack;");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKESTATIC, "org/bukkit/craftbukkit/" + this.version + "/inventory/CraftItemStack", "asNMSCopy",
					"(Lorg/bukkit/inventory/ItemStack;)Lnet/minecraft/server/" + this.version + "/ItemStack;");
			mv.visitFieldInsn(PUTFIELD, "chenji/asmuntl/NMSItemCopy", "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;");
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;");
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/ItemStack", "getTag", "()Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitFieldInsn(PUTFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			Label l3 = new Label();
			mv.visitLabel(l3);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			Label l4 = new Label();
			mv.visitJumpInsn(IFNONNULL, l4);
			Label l5 = new Label();
			mv.visitLabel(l5);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitTypeInsn(NEW, "net/minecraft/server/" + this.version + "/NBTTagCompound");
			mv.visitInsn(DUP);
			mv.visitMethodInsn(INVOKESPECIAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "<init>", "()V");
			mv.visitFieldInsn(PUTFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitLabel(l4);
			mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l6 = new Label();
			mv.visitLabel(l6);
			mv.visitMaxs(3, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getItem", "()Lorg/bukkit/inventory/ItemStack;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;");
			mv.visitMethodInsn(INVOKESTATIC, "org/bukkit/craftbukkit/" + this.version + "/inventory/CraftItemStack", "asBukkitCopy",
					"(Lnet/minecraft/server/" + this.version + "/ItemStack;)Lorg/bukkit/inventory/ItemStack;");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(1, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setString", "(Ljava/lang/String;Ljava/lang/String;)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setString", "(Ljava/lang/String;Ljava/lang/String;)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setShort", "(Ljava/lang/String;S)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ILOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setShort", "(Ljava/lang/String;S)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getNBTTagCompound", "()Ljava/lang/Object;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;");
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/ItemStack", "getTag", "()Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(1, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getNMSItemStack", "()Ljava/lang/Object;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "nmsItem", "Lnet/minecraft/server/" + this.version + "/ItemStack;");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(1, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setInteger", "(Ljava/lang/String;I)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ILOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setInt", "(Ljava/lang/String;I)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setLong", "(Ljava/lang/String;J)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(LLOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setLong", "(Ljava/lang/String;J)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(4, 4);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setBoolean", "(Ljava/lang/String;Z)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ILOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setBoolean", "(Ljava/lang/String;Z)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setDouble", "(Ljava/lang/String;D)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(DLOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setDouble", "(Ljava/lang/String;D)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(4, 4);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setFloat", "(Ljava/lang/String;F)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(FLOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setFloat", "(Ljava/lang/String;F)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setByteArray", "(Ljava/lang/String;[B)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setByteArray", "(Ljava/lang/String;[B)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setIntegerArray", "(Ljava/lang/String;[I)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ALOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setIntArray", "(Ljava/lang/String;[I)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "setByte", "(Ljava/lang/String;B)Lchenji/gunapi/untl/nbt/NMSItem;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitVarInsn(ILOAD, 2);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "setByte", "(Ljava/lang/String;B)V");
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitInsn(ARETURN);
			Label l2 = new Label();
			mv.visitLabel(l2);
			mv.visitMaxs(3, 3);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getInteger", "(Ljava/lang/String;)I", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getInt", "(Ljava/lang/String;)I");
			mv.visitInsn(IRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getLong", "(Ljava/lang/String;)J", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getLong", "(Ljava/lang/String;)J");
			mv.visitInsn(LRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getBoolean", "(Ljava/lang/String;)Z", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getBoolean", "(Ljava/lang/String;)Z");
			mv.visitInsn(IRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getDouble", "(Ljava/lang/String;)D", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getDouble", "(Ljava/lang/String;)D");
			mv.visitInsn(DRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getFloat", "(Ljava/lang/String;)F", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getFloat", "(Ljava/lang/String;)F");
			mv.visitInsn(FRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getByteArray", "(Ljava/lang/String;)[B", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getByteArray", "(Ljava/lang/String;)[B");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getIntegerArray", "(Ljava/lang/String;)[I", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getIntArray", "(Ljava/lang/String;)[I");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getByte", "(Ljava/lang/String;)B", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getByte", "(Ljava/lang/String;)B");
			mv.visitInsn(IRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getString", "(Ljava/lang/String;)Ljava/lang/String;", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getString", "(Ljava/lang/String;)Ljava/lang/String;");
			mv.visitInsn(ARETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "getShort", "(Ljava/lang/String;)S", null, null);
			mv.visitCode();
			Label l0 = new Label();
			mv.visitLabel(l0);
			mv.visitVarInsn(ALOAD, 0);
			mv.visitFieldInsn(GETFIELD, "chenji/asmuntl/NMSItemCopy", "tag", "Lnet/minecraft/server/" + this.version + "/NBTTagCompound;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/server/" + this.version + "/NBTTagCompound", "getShort", "(Ljava/lang/String;)S");
			mv.visitInsn(IRETURN);
			Label l1 = new Label();
			mv.visitLabel(l1);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		cw.visitEnd();

		return cw.toByteArray();
	}

	public Class<? extends NMSItem> getNMSItemCopyClass() {
		return this.nmsItemCopyClass;
	}
}
